
import types, copy
from core import AbstractTag, PytmlError
from doctype import Doctype
from content import Content

__all__=['Tag']

class Tag(AbstractTag):
    def __init__(self, inTagType):
        AbstractTag.__init__(self, inTagType)

        self.__attributes = {}

    def addTag(self, inTag, inPosition=-1):
        newTag = None
        if type(inTag) in types.StringTypes:
            newTag = Tag(inTag)
            newTag.setParentTag(self, inPosition)
        elif isinstance(inTag, AbstractTag):
            inTag.setParentTag(self, inPosition)
            newTag = inTag
        else:
            raise PytmlError, 'addTag accepts only string or a Tag instance as argument. Got %s instead' %inTag
        return newTag

    def addContent(self, inContent, inContentType=Content.string, inPosition=-1):
        content = Content()
        content.set(inContent)
        content.setContentType(inContentType)
        self.addTag(content, inPosition)

    def getAttributes(self):
        return copy.copy(self.__attributes)

    def getAttribute(self, inAttributeName):
        return self.__attributes[inAttributeName]

    def addAttribute(self, inAttributeName, inAttributeValue):
        self.__attributes[inAttributeName] = inAttributeValue

    def removeAttribute(self, inAttributeName):
        return self.__attributes.pop(inAttributeName)

    def toString(self, tab=0, doctype=Doctype('XHTML', 'Strict')):
        childrenTags = self._getChildrenTagsByReference()
        childrenLength = len(childrenTags)

        # Is there need to break the line? (in the final output string)
        # Only if this Tag has more than 1 child or, in the case it has 1 child,
        # if this child has 1 or more children
        breakLine = (childrenLength == 1 and isinstance(childrenTags[0], Content) and len(childrenTags[0].getChildrenTags())>1) \
                    or (childrenLength == 1 and not isinstance(childrenTags[0], Content) and len(childrenTags[0].getChildrenTags())>0) \
                    or childrenLength > 1


        # Get a string for every attribute, appropriately formatted
        attributesString = ''
        for attribute in self.getAttributes():
            value = self.getAttributes()[attribute]
            if value:
                attributesString += ' %s="%s"' %(attribute, str(value))

        # Start the final output string, this provide something like <div class="myClass" id="3">
        # already appropriately indented
        output = '\t'*tab+'<%s%s>' %(self.getType(), attributesString)

        # Now for every element in the content list (children + lines of content), get the html string
        # Note how breakLine is used here for make a new line or not, so that the output is always gracious
        for child in childrenTags:
            output += '\n'*breakLine + child.toString((tab+1)*breakLine, doctype)

        # And finally close the tag, appropriately indented and in a new line if required
        if doctype and doctype.getType() == 'XHTML' and len(childrenTags) == 0:
            output = output[:-1]+' />'
        else:
            output += ('\n'+'\t'*tab)*breakLine + '</%s>' %(self.getType())

        return output

